#pragma once

#include "format.h"
#include <d3d11.h>
#include <vector>
#include "animation.h"

class TextureMgr;

class MeshGeometry
{
public: MeshGeometry();
		~MeshGeometry();
		template <typename VertexType>
		void SetVertices(ID3D11Device* device,
			const VertexType* vertices, UINT count);
		void SetIndices(ID3D11Device* device,
			const UINT* indices, UINT count);
		void SetSubsetTable(std::vector<Subset>& subsetTable);
		void Draw(ID3D11DeviceContext* dc, UINT subsetId);
private:
	MeshGeometry(const MeshGeometry& rhs);
	MeshGeometry& operator=(const MeshGeometry& rhs);
private:
	ID3D11Buffer* mVB;
	ID3D11Buffer* mIB;
	DXGI_FORMAT mIndexBufferFormat; // Always 32-bit
	// Cache sizeof(VertexType) to pass to IASetVertexBuffers
	UINT mVertexStride;
	std::vector<Subset> mSubsetTable;
};


class BaseModel
{
public:
	BaseModel(ID3D11Device* device,
		TextureMgr& texMgr,
		const std::string& modelFilename,
		const std::wstring& texturePath);
	~BaseModel();

	void Update(float timePos);
	void UpdateWorldMatrix(const XMFLOAT4X4& M);
	void Draw(ID3D11DeviceContext* dc);

	UINT SubsetCount;

	std::vector<Material> Mats;
	std::vector<ID3D11ShaderResourceView*> DiffuseMapSRV;
	std::vector<ID3D11ShaderResourceView*> NormalMapSRV;

	// Keep CPU copies of the mesh data to read from.
	std::vector<PosVertex> Vertices;
	std::vector<UINT> Indices;
	std::vector<Subset> Subsets;
	MeshGeometry ModelMesh;

	SkinnedData mSkinnedData;
	std::string mClipName;

	ID3D11Buffer* mCBPerObj;
	XMFLOAT4X4 mWorld;
	XMFLOAT4X4 mWorldInvTrans;

	ID3D11Buffer* mCBBoneTransforms;
	std::vector<XMMATRIX> mBoneTransforms;
};

